(function() {
    'use strict';

    /**
     * 各种常用的方法存储在这里
     */
    angular.module('webApp')

    .factory('helper', ['$timeout', '$filter', 'md5', '$sce', function($timeout, $filter, md5, $sce) {

        this.phtml=function(html){
            return html.replace(/[\'\"\\\/\b\f\n\r\t]/g, '');
        }

        this.px2pt = function(px) {
            return px * 1;
        }

        this.guid = function() {
            function s4() {
                return Math.floor((1 + Math.random()) * 0x10000)
                    .toString(16)
                    .substring(1);
            }
            return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
                s4() + '-' + s4() + s4() + s4();
        }

        this.guid24 = function() {
            function s4() {
                return Math.floor((1 + Math.random()) * 0x10000)
                    .toString(16)
                    .substring(1);
            }
            return s4() + s4() + s4() + s4() + s4() + s4();
        }


        /*****************
        页面右下角显示消息
        ******************/
        this.message = function(msg, type, wait) {
            var mid = md5.createHash(msg);
            if (angular.element("#" + mid).length > 0) return;
            $timeout(function() {
                // type 可选值：sussess  error
                wait = _.isNumber(wait) ? wait : 3;
                // standard notification
                // setting the wait property to 0 will
                // keep the log message until it's clicked
                alertify.log("<span id='" + mid + "'>" + msg + "</span>", type, wait * 1000);
            });
        }

        /*****************
        在元素上面显示消息
        <button ng-click="abc(a,$event);">保存</button>

        $scope.acb(a,$event){
            //.......
            helper.myTip("更新成功！", $event.currentTarget);
        }
        ******************/

        this.myTip = function(msg, elm, url, timeout, cb, po, style) {
            $timeout(function() {
                timeout = timeout || 2;
                po = po || 'top';
                var pp = {
                    top: "hint--top",
                    right: "hint--right",
                    bottom: "hint--bottom",
                    left: "hint--left",
                }

                var tp = {
                    error: "hint--error",
                    warning: "hint--warning",
                    info: "hint--info",
                    success: "hint--success",
                }
                var tt = " " + tp[style] || "";


                var hintClass = "hint--always hint--bounce " + pp[po] + tt;
                $(elm).addClass(hintClass);

                $(elm).attr("aria-label", $filter('translate')(msg));
                $timeout(function() {
                    $(elm).removeClass(hintClass);
                    if (url) {
                        location.href = url;
                    }
                    if (cb) {
                        cb();
                    }
                }, timeout * 1000);
            });
        }

        this.myTip2 = function(msg, elm, url, timeout, cb, po) {
                var distroy = false;
                timeout = timeout || 2;
                po = po || 'top';

                $(elm).tooltip({
                    animation: false,
                    type: 'default',
                    placement: po,
                    html: true,
                    title: msg,
                    width: '300%',
                    delay: { show: 400, hide: 3000 },
                    hide: function() {
                        if (!distroy) {
                            distroy = true;
                            $(elm).tooltip('destroy');
                            if (url) {
                                location.href = url;
                            }
                            if (cb) {
                                cb();
                            }
                        }
                    }
                }).tooltip('show');
            }
            /*****************
        移除所有弹窗
        ******************/
        this.rmAlert = rmAlert
            //移出遮罩背景
        this.rmbdbg = rmbdbg
            /*****************
            消息弹窗
            msg: string 弹窗中显示的文字
            url: 窗口关闭后切换到url
            timeout: 消息延时多少秒自动关闭窗口
            cb: 窗口关闭回调函数
            ******************/
        this.myAlert = function(msg, url, timeout, cb) {
            timeout = timeout || 3;
            $.alert({
                // backdrop: 'static',
                keyboard: true,
                title: '<i class="sui-icon icon-tb-notification"></i> <small id="myAlertCloseBtn"></small>',
                body: $filter('translate')(msg),
                okBtn: $filter('translate')('close'),
                closeBtn: true,
                transition: true,
                timeout: timeout * 1000,
                width: 'small',
                shown: function() {
                    timeMsg();

                    function timeMsg() {
                        // console.log("倒计时：", timeout);
                        setTimeout(function() {
                            $("#myAlertCloseBtn").html('（' + timeout + 's）');
                            if (timeout > 0) {
                                timeMsg();
                            }
                        }, 1000);
                        timeout -= 1;
                    }
                },
                hide: function(e) {
                    if (url) {
                        location.href = url;
                    }
                    if (cb)
                        cb();
                }
            });
        }

        /*****************
        确认弹窗
        msg: string 弹窗中显示的文字
        okcb: function 确认后的回调函数
        nocb: function 取消后的回调函数
        ******************/
        this.myConfirm = function(msg, okcb, nocb) {
            var m = _.isString(msg) ? msg : msg.msg;
            m = m || "ok_or_no";
            var haveInput = _.isObject(msg) && msg.remark;
            var body = $filter('translate')(m);
            if (haveInput) {
                body += '<br><textarea id="confirmRemark" style="width:98%;height:100px;"></textarea>'
            }

            function remark() {
                if (_.isString(msg)) return '';
                if (!haveInput) return '';
                var r = $("#confirmRemark").val();
                if (!r) {
                    alert($filter('translate')('required'));
                    return false;
                } else {
                    return r;
                }
            }

            $.confirm({
                backdrop: 'static',
                keyboard: true,
                title: '<i class="sui-icon icon-tb-notification"></i>',
                body: body,
                okBtn: $filter('translate')('ok'),
                cancelBtn: $filter('translate')('cancel'),
                closeBtn: true,
                transition: true,
                width: 'small',
                okHide: function() {
                    var rk = remark();
                    if (rk === false) return false;

                    if (okcb) {
                        okcb(rk);
                    }
                    return true;
                },
                cancelHide: function(e) {
                    var rk = remark();
                    if (rk === false) return false;

                    if (nocb) {
                        nocb(rk);
                    }
                    return true;
                }
            });
        }
        return this;
    }]);
})();

//跳转
function gourl(url) {
    location.href = url;
}

/*****************
产生一个随机整数
最大值是max
******************/
function random(max) {
    max = max || 100;
    return Math.floor(Math.random() * max);
}

function randomKey() {
    var max = 999999;
    return String(Math.floor(Math.random() * max));
}


/****************
删除弹窗
****************/
function rmAlert() {
    console.log("删除弹窗")
    var result1 = document.getElementsByClassName("sui-modal");
    var result2 = document.getElementsByClassName("sui-modal-backdrop");
    var multibutton1 = angular.element(result1);
    var multibutton2 = angular.element(result2);
    multibutton1.remove();
    multibutton2.remove();
    loadingToggle(true);
}
/********
移出遮罩层
********/
function rmbdbg() {
    var result2 = document.getElementsByClassName("sui-modal-backdrop");
    var multibutton2 = angular.element(result2);
//     console.error("ddddddddddddddddddddd");
    multibutton2.remove();

}

/*****************
克隆一个对象
obj：任意js对象
******************/
function loadingToggle(f) {
    if (f) {
        $("#initloadingdiv").hide();
        $("#bodydiv").show();
        $(".sui-modal-backdrop").removeClass("login-modal");
    } else {
        $("#initloadingdiv").show();
        $("#bodydiv").hide();
        $(".sui-modal-backdrop").addClass("login-modal");
    }
}

/*****************
克隆一个对象
obj：任意js对象
******************/
function clone(obj) {
    if (!obj) return obj;
    return JSON.parse(angular.toJson(obj));
}
/***************** 
根据坐标字符串 解析成 位置对象 
 possize = 坐标 宽高
******************/
function ParePossize(possize) {
    var posobj = {
        'x': 0,
        'y': 0,
        'width': 110,
        'height': 20
    };
    var arrpos = possize.split(',');
    if (arrpos[0] != undefined) {
        if (arrpos[0].indexOf('px') > 0) {
            posobj.x = arrpos[0].replace('px', '');
        } else {
            posobj.x = arrpos[0];
        }
    }
    if (arrpos[1] != undefined) {
        if (arrpos[1].indexOf('px') > 0) {
            posobj.y = arrpos[1].replace('px', '');
        } else {
            posobj.y = arrpos[1];
        }
    }
    if (arrpos[2] != undefined) {
        if (arrpos[2].indexOf('px') > 0) {
            posobj.width = arrpos[2].replace('px', '');
        } else {
            posobj.width = arrpos[2];
        }
    }
    if (arrpos[3] != undefined) {
        if (arrpos[3].indexOf('px') > 0) {
            posobj.height = arrpos[3].replace('px', '');
        } else {
            posobj.height = arrpos[3];
        }
    }
    return posobj;
}

/***************** 
生成标签html结构
名字 坐标 宽高 type 1-自定义标签 2-变量 flg  是否是自定义标签
******************/

function MakeOnetagHtml(name, possize, type, family, size, weight, space, imgurl, flg, id) {
    var htmlstr = "",
        stylestr = "",
        cls = "";
    var posobj = ParePossize(possize);
    var picurl = imgurl;
    //根据不同类型 拼装标签的  html结构...
    var y = 0;
    stylestr = 'left:' + posobj.x + 'px;top:' + posobj.y + 'px';
    //有宽高
    if (posobj.width != undefined) {
        stylestr += ';width:' + posobj.width + "px;height:" + posobj.height + "px";
    }
    //有字体样式
    if (family != undefined) {
        stylestr += ';font-family:' + family;
    }
    //字体大小
    if (size != undefined) {
        stylestr += ';font-size:' + size;
    }
    //字体加粗
    if (weight != undefined) {
        stylestr += ';font-weight:' + weight;
    }
    //字体换行
    if (space != undefined) {
        stylestr += ';white-space:' + space;
    } else {
        stylestr += ';white-space:normal'; //可换行
    }

    if (type == 1 || type == 5) { //自定义标签 可编辑
        cls += 'editable-ele';
    }
    if (flg != undefined) {
        cls += 'editable-ele';
    }

    stylestr += ';line-height:normal;position: absolute';
    // console.log("stylestr", stylestr, id);
    htmlstr += '<div class="element ' + cls + '" style="' + stylestr + '" id="' + id + '">';
    htmlstr += '<div class="for-overflow">';
    htmlstr += '<font>' + name + '</font>';
    if (type == 1 || flg != undefined || type == 5) { //自定义标签 可编辑
        htmlstr += '<a class="edit"></a>';
    }
    htmlstr += '<a class="delete"></a>';
    htmlstr += '</div>';
    htmlstr += '</div>';
    // console.log("htmlstr", htmlstr);
    return htmlstr;
}


function deepExtend(obj) {
  var parentRE = /#{\s*?_\s*?}/,
      source,
  
      isAssign = function (oProp, sProp) {
        return (_.isUndefined(oProp) || _.isNull(oProp) || _.isFunction(oProp) || _.isNull(sProp) || _.isDate(sProp));
      },
  
      procAssign = function (oProp, sProp, propName) {
        // Perform a straight assignment
        // Assign for object properties & return for array members
        return obj[propName] = _.clone(sProp);
      },
  
      hasRegex = function (oProp, sProp) {
        return ( _.isString(sProp) && parentRE.test(sProp) );
      },
  
      procRegex = function (oProp, sProp, propName) {
        // Perform a string.replace using parentRE if oProp is a string
        if (!_.isString(oProp)) {
          // We're being optimistic at the moment
          // throw new Error('Trying to combine a string with a non-string (' + propName + ')');
        }
        // Assign for object properties & return for array members
        return obj[propName] = sProp.replace(parentRE, oProp);
      },
  
      hasArray = function (oProp, sProp) {
        return (_.isArray(oProp) || _.isArray(sProp));
      },
  
      procArray = function (oProp, sProp, propName) {
        // extend oProp if both properties are arrays
        if (!_.isArray(oProp) || !_.isArray(sProp)){
          throw new Error('Trying to combine an array with a non-array (' + propName + ')');
        }
        var tmp = _.deepExtend(obj[propName], sProp);
        // Assign for object properties & return for array members
        return obj[propName] = _.reject(tmp, _.isNull);
      },
  
      hasObject = function (oProp, sProp) {
        return (_.isObject(oProp) || _.isObject(sProp));
      },
  
      procObject = function (oProp, sProp, propName) {
        // extend oProp if both properties are objects
        if (!_.isObject(oProp) || !_.isObject(sProp)){
          throw new Error('Trying to combine an object with a non-object (' + propName + ')');
        }
        // Assign for object properties & return for array members
        return obj[propName] = _.deepExtend(oProp, sProp);
      },

      procMain = function(propName) {
        var oProp = obj[propName],
            sProp = source[propName];
          
        // The order of the 'if' statements is critical
        
        // Cases in which we want to perform a straight assignment
        if ( isAssign(oProp, sProp) ) {
          procAssign(oProp, sProp, propName);
        }
        // sProp is a string that contains parentRE
        else if ( hasRegex(oProp, sProp) ) {
          procRegex(oProp, sProp, propName);
        }
        // At least one property is an array
        else if ( hasArray(oProp, sProp) ){
          procArray(oProp, sProp, propName);
        }
        // At least one property is an object
        else if ( hasObject(oProp, sProp) ){
          procObject(oProp, sProp, propName);
        }
        // Everything else
        else {
          // Let's be optimistic and perform a straight assignment
          procAssign(oProp, sProp, propName);
        }
      },
  
      procAll = function(src) {
        source = src;
        Object.keys(source).forEach(procMain);
      };

  _.each(Array.prototype.slice.call(arguments, 1), procAll);
  
  return obj;
};

_.mixin({ 'deepExtend': deepExtend });
